package controller

import (
	"easyreport/conf"
	"easyreport/conn"
	"easyreport/model"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"strings"
)

type Controller struct {
}
type IndexController struct {
}

func (m *IndexController) Find(c *gin.Context) {
	name := c.Query("name")
	cur, _ := strconv.Atoi(c.Query("cur"))
	size, _ := strconv.Atoi(c.Query("size"))

	sql := `select * from sys_reports `
	var sqlorArgs []interface{}
	sqlorArgs = append(sqlorArgs, sql)
	if name != "" {
		sql += " where NAME like '%'||?||'%' or ID like '%'||?||'%'"
		sqlorArgs = append(sqlorArgs, name)
		sqlorArgs = append(sqlorArgs, name)
	}
	sql = sql + " order by id desc"

	countSql := "SELECT COUNT(1) as mcount FROM (" + sql + ")"
	sqlorArgs[0] = countSql
	cdata, err := conn.DB["def"].Query(sqlorArgs...)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": "01", "msg": err.Error()})
		return
	}
	count := cdata[0]["MCOUNT"]
	if conf.Get().Pool["def"]["dialect"].(string) == "mysql" {
		sql = sql + " limit ?,?"
		sqlorArgs = append(sqlorArgs, (cur-1)*size)
		sqlorArgs = append(sqlorArgs, size)
	} else {
		sql = " SELECT T.* FROM (SELECT T.*, ROWNUM RN FROM (" + sql + ") T WHERE ROWNUM <= ?) T WHERE RN > ? "
		sqlorArgs = append(sqlorArgs, cur*size)
		sqlorArgs = append(sqlorArgs, (cur-1)*size)
	}

	sqlorArgs[0] = sql
	result, err := conn.DB["def"].Query(sqlorArgs...)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": "01", "msg": err.Error()})
		return
	}
	dest := DataToStruct(result)
	c.JSON(http.StatusOK, gin.H{"code": "0", "msg": "", "data": dest, "total": fmt.Sprintf("%s", count)})

}

func (m *IndexController) Get(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		return
	}
	sql := `select * from sys_reports where ID=?`
	var sqlorArgs []interface{}
	sqlorArgs = append(sqlorArgs, sql)
	sqlorArgs = append(sqlorArgs, id)
	result, err := conn.DB["def"].Query(sqlorArgs...)
	if err != nil {
		fmt.Println(err)
		return
	}
	dest := DataToStruct(result)
	c.JSON(http.StatusOK, dest)
}

func DataToStruct(result []map[string][]byte) []model.SysReports {
	var dest []model.SysReports
	item := model.SysReports{}
	for _, im := range result {
		item.Id = string(im["ID"])
		item.Name = string(im["NAME"])
		item.Params = string(im["PARAMS"])

		var title []string
		json.Unmarshal(im["COLS_TITLE"], &title)
		item.ColsTitle = title

		var enTitle []string
		json.Unmarshal(im["COLS_EN_NAME"], &enTitle)
		item.ColsEnName = enTitle

		var funcType []string
		json.Unmarshal(im["FUNC_TYPE"], &funcType)
		item.FuncType = funcType
		item.ExecSql = string(im["EXEC_SQL"])

		var sqlWhere []string
		json.Unmarshal(im["SQL_WHERE"], &sqlWhere)
		item.SqlWhere = sqlWhere

		var groupTitle []string
		json.Unmarshal(im["GROUP_TITLE"], &groupTitle)
		item.GroupTitle = groupTitle
		item.Type = string(im["TYPE"])
		item.EnCode = string(im["EN_CODE"])
		dest = append(dest, item)
	}
	return dest
}

func (m *Controller) Auth(dm string, c *gin.Context) bool {
	redisCli := conn.Redis[dm]
	redisConf := conf.Get().Redis[dm]
	if redisCli == nil {
		redisCli = conn.Redis["def"]
		redisConf = conf.Get().Redis["def"]
	}
	if redisCli != nil {
		token, err := c.Cookie(redisConf["cookieName"].(string))
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"code": "01", "msg": "安全认证失败！"})
			c.Abort()
			return false
		}
		id := redisCli.Get(token)
		if id == nil {
			c.JSON(http.StatusOK, gin.H{"code": "01", "msg": "安全认证失败！"})
			c.Abort()
			return false
		}
	}
	return true
}

func (m *IndexController) Post(c *gin.Context) {
	sys := new(model.SysReports)
	err := c.BindJSON(sys)
	if err != nil {
		fmt.Println(err)
		return
	}
	sql := `select * from sys_reports where ID=?`
	var sqlorArgs []interface{}
	sqlorArgs = append(sqlorArgs, sql)
	sqlorArgs = append(sqlorArgs, sys.Id)
	result, err := conn.DB["def"].Query(sqlorArgs...)
	if err != nil {
		fmt.Println(err)
		return
	}
	if len(result) != 0 {
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "主键已存在！"})
		return
	}

	sql = `INSERT INTO SYS_REPORTS(ID,NAME,PARAMS,COLS_TITLE,COLS_EN_NAME,FUNC_TYPE,EXEC_SQL,SQL_WHERE,GROUP_TITLE,TYPE,EN_CODE)
		VALUES(?,?,?,?,?,?,?,?,?,?,?)`
	title, _ := json.Marshal(sys.ColsTitle)
	groupTitle, _ := json.Marshal(sys.GroupTitle)
	enTitle, _ := json.Marshal(sys.ColsEnName)
	funcType, _ := json.Marshal(sys.FuncType)
	sqlWhere, _ := json.Marshal(sys.SqlWhere)

	_, err = conn.DB["def"].Exec(sql, sys.Id, sys.Name, sys.Params, string(title), strings.ToUpper(string(enTitle)),
		strings.ToUpper(string(funcType)), string(sys.ExecSql), string(sqlWhere), string(groupTitle), sys.Type, sys.EnCode)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "插入失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "插入成功"})
}

func (m *IndexController) Put(c *gin.Context) {
	id := c.Param("id")
	sys := new(model.SysReports)
	err := c.BindJSON(sys)
	if err != nil {
		fmt.Println(err)
		return
	}
	sql := `UPDATE SYS_REPORTS SET NAME=?,PARAMS=?,COLS_TITLE=?,COLS_EN_NAME=?,FUNC_TYPE=?,
		EXEC_SQL=?,SQL_WHERE=?,GROUP_TITLE=?,TYPE=?,EN_CODE=? WHERE ID=? `
	title, _ := json.Marshal(sys.ColsTitle)
	groupTitle, _ := json.Marshal(sys.GroupTitle)
	enTitle, _ := json.Marshal(sys.ColsEnName)
	funcType, _ := json.Marshal(sys.FuncType)
	sqlWhere, _ := json.Marshal(sys.SqlWhere)

	_, err = conn.DB["def"].Exec(sql, sys.Name, sys.Params, string(title), strings.ToUpper(string(enTitle)),
		strings.ToUpper(string(funcType)), string(sys.ExecSql), string(sqlWhere),
		string(groupTitle), sys.Type, sys.EnCode, id)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "修改失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "修改成功"})
}

func (m *IndexController) Delete(c *gin.Context) {
	id := c.Param("id")
	if id != "" {
		_, err := conn.DB["def"].Exec("delete from sys_reports where ID=?", id)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "删除失败"})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "删除成功"})
}

func inWhere(n int) string {
	ps := make([]string, n)
	for i := 0; i < n; i++ {
		ps[i] = "?"
	}
	return strings.Join(ps, ",")
}

func (m *IndexController) PageView(c *gin.Context) {
	id := c.Query("id")
	if id == "" {
		id = ""
	}
	c.HTML(http.StatusOK, c.Param("name"), gin.H{"id": id,})
}
